package cn.iocoder.yudao.module.erp.controller.admin.contractinfo;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.customerinfo.vo.CustomerInfoSimpleVO;
import cn.iocoder.yudao.module.erp.controller.admin.monthplaninfo.vo.NameExistVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.customerinfo.CustomerInfoDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.monthplaninfo.MonthPlanInfoDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.planinfo.PlanInfoDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
import cn.iocoder.yudao.module.erp.dal.mysql.contractinfo.ContractInfoMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.customerinfo.CustomerInfoMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.planinfo.PlanInfoMapper;
import cn.iocoder.yudao.module.erp.enums.DictTypeConstants;
import cn.iocoder.yudao.module.erp.service.customerinfo.CustomerInfoService;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;

import cn.iocoder.yudao.module.erp.controller.admin.contractinfo.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.contractinfo.ContractInfoDO;
import cn.iocoder.yudao.module.erp.service.contractinfo.ContractInfoService;

@Tag(name = "管理后台 - 合同信息")
@RestController
@RequestMapping("/erp/contract-info")
@Validated
public class ContractInfoController {

    @Resource
    private ContractInfoService contractInfoService;

    @Resource
    private CustomerInfoService customerInfoService;

    @Resource
    private CustomerInfoMapper customerInfoMapper;

    @Resource
    private ContractInfoMapper contractInfoMapper;

    @Resource
    private PlanInfoMapper planInfoMapper;

    @PostMapping("/create")
    @Operation(summary = "创建合同信息")
    @PreAuthorize("@ss.hasPermission('erp:contract-info:create')")
    public CommonResult<Long> createContractInfo(@Valid @RequestBody ContractInfoSaveReqVO createReqVO) {
        return success(contractInfoService.createContractInfo(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新合同信息")
    @PreAuthorize("@ss.hasPermission('erp:contract-info:update')")
    public CommonResult<Boolean> updateContractInfo(@Valid @RequestBody ContractInfoSaveReqVO updateReqVO) {
        contractInfoService.updateContractInfo(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除合同信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('erp:contract-info:delete')")
    public CommonResult<Boolean> deleteContractInfo(@RequestParam("id") Long id) {
        contractInfoService.deleteContractInfo(id);
        return success(true);
    }


    @GetMapping("/calculateContrantCount")
    @Operation(summary = "重置合同量")
    public CommonResult<Boolean> calculateContrantCount() {
        List<ContractInfoDO> list=contractInfoMapper.selectList();
        for(ContractInfoDO con:list){
            //c重置合同量
            con.setUsedCount(new BigDecimal(0));
            if(con.getType().equals("1")){
                List<PlanInfoDO> planList=planInfoMapper.selectList(new LambdaQueryWrapperX<PlanInfoDO>().eq(PlanInfoDO::getStatus,"1").eq(PlanInfoDO::getBuyContractId,con.getId())
                        .select(PlanInfoDO::getBuyRealCount,PlanInfoDO::getId));
                if(planList!=null&&planList.size()>0){
                    BigDecimal sum = planList.stream().map(PlanInfoDO::getBuyRealCount)
                            .reduce(BigDecimal.ZERO, (a, b) -> a.add(b));
                    con.setUsedCount(sum);
                }
            }else if(con.getType().equals("2")){
                List<PlanInfoDO> planList=planInfoMapper.selectList(new LambdaQueryWrapperX<PlanInfoDO>().eq(PlanInfoDO::getStatus,"1").eq(PlanInfoDO::getSaleContractId,con.getId())
                        .select(PlanInfoDO::getSaleRealCount,PlanInfoDO::getId));
                if(planList!=null&&planList.size()>0){
                    BigDecimal sum = planList.stream().map(PlanInfoDO::getSaleRealCount)
                            .reduce(BigDecimal.ZERO, (a, b) -> a.add(b));
                    con.setUsedCount(sum);
                }
            }
        }
        contractInfoMapper.updateBatch(list);
        return success(true);
    }

    @GetMapping("/getNameisExist")
    @Operation(summary = "查询名称是否已存在")
    public CommonResult<Boolean> getNameisExist(/*@RequestParam("name") String name*/NameExistVO exist) {
        if(StringUtils.isBlank(exist.getName())){
            return success(false);
        }
        Long count= contractInfoMapper.selectCount(new LambdaQueryWrapperX<ContractInfoDO>().eq(ContractInfoDO::getName,exist.getName()).neIfPresent(ContractInfoDO::getId,exist.getId()));
        if(count>0){
            return success(false);
        }else{
            return success(true);
        }


    }


    @GetMapping("/get")
    @Operation(summary = "获得合同信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:contract-info:query')")
    public CommonResult<ContractInfoRespVO> getContractInfo(@RequestParam("id") Long id) {
        ContractInfoDO contractInfo = contractInfoService.getContractInfo(id);
        return success(BeanUtils.toBean(contractInfo, ContractInfoRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得合同信息分页")
    @PreAuthorize("@ss.hasPermission('erp:contract-info:query')")
    public CommonResult<PageResult<ContractInfoRespVO>> getContractInfoPage(@Valid ContractInfoPageReqVO pageReqVO) {
        PageResult<ContractInfoDO> pageResult = contractInfoService.getContractInfoPage(pageReqVO);

        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty(pageResult.getTotal()));
        }
        // 客户信息
        List<CustomerInfoDO> customerList = customerInfoService.getCustomerListIds(
                convertSet(pageResult.getList(), ContractInfoDO::getCustomerId));
        Map<Long,CustomerInfoDO> customerMap=customerList.stream().collect(Collectors.toMap(CustomerInfoDO::getId, e -> e));


       // return success(BeanUtils.toBean(pageResult, ContractInfoDO.class));
       // return success(pageResult);
        //return success(BeanUtils.toBean(pageResult, ContractInfoRespVO.class));
        return success(BeanUtils.toBean(pageResult, ContractInfoRespVO.class, plan -> {
            MapUtils.findAndThen(customerMap, plan.getCustomerId(), cus -> plan.setCustomerName(cus.getName()));


            //照付不议描述
            BigDecimal needFinsh=plan.getContractCount().multiply(plan.getRatio()).setScale(2, RoundingMode.HALF_UP);
            if(plan.getUsedCount().compareTo(needFinsh)>=0){
                plan.setRatioFinish(true);
                plan.setRatioDescible("已完成");
            }else{
                plan.setRatioFinish(false);
                BigDecimal lack=needFinsh.subtract(plan.getUsedCount());
                BigDecimal strippedNumber = lack.stripTrailingZeros();
                plan.setRatioDescible("剩余应完成："+strippedNumber.toPlainString());
            }

        }));
    }


    @GetMapping("/simple-list")
    @Operation(summary = "获得合同精简列表", description = "获得合同精简列表，主要用于前端的下拉选项")
    public CommonResult<List<ContractInfoSimpleVO>> getProductCategorySimpleList(@RequestParam("type") Long type,@RequestParam("customerId") String customerId ) {
        Long cId= StringUtils.isNotBlank(customerId)?Long.valueOf(customerId):null;
        List<ContractInfoDO> list = contractInfoMapper.selectList(new LambdaQueryWrapperX<ContractInfoDO>().eqIfPresent(ContractInfoDO::getType,type)
                .eqIfPresent(ContractInfoDO::getCustomerId,cId).orderByDesc(ContractInfoDO::getCreateTime));

        return success(convertList(list, customer -> new ContractInfoSimpleVO().setId(customer.getId()).setName(customer.getName())));
    }





    private PageResult<ContractInfoRespVO> buildContractInfoVOResult(PageResult<ContractInfoDO> pageResult) {
        if (CollUtil.isEmpty(pageResult.getList())) {
            return PageResult.empty(pageResult.getTotal());
        }
        // 客户信息
        List<CustomerInfoDO> customerList = customerInfoService.getCustomerListIds(
                convertSet(pageResult.getList(), ContractInfoDO::getCustomerId));
        Map<Long,CustomerInfoDO> customerMap=customerList.stream().collect(Collectors.toMap(CustomerInfoDO::getId, e -> e));


        return BeanUtils.toBean(pageResult, ContractInfoRespVO.class, purchaseIn -> {
            MapUtils.findAndThen(customerMap, purchaseIn.getCustomerId(), cus -> purchaseIn.setCustomerName(cus.getName()));
        });
    }



    @GetMapping("/export-excel")
    @Operation(summary = "导出合同信息 Excel")
    @PreAuthorize("@ss.hasPermission('erp:contract-info:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportContractInfoExcel(@Valid ContractInfoPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ContractInfoDO> list = contractInfoService.getContractInfoPage(pageReqVO).getList();

        // 客户信息
        List<CustomerInfoDO> customerList = customerInfoMapper.selectList();
        Map<Long,CustomerInfoDO> customerMap=customerList.stream().collect(Collectors.toMap(CustomerInfoDO::getId, e -> e));

        List<ContractInfoRespVO> rlist=BeanUtils.toBean(list, ContractInfoRespVO.class, purchaseIn -> {
            MapUtils.findAndThen(customerMap, purchaseIn.getCustomerId(), cus -> purchaseIn.setCustomerName(cus.getName()));
            purchaseIn.setStatusName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.COMMON_STATUS, purchaseIn.getStatus()));
            purchaseIn.setTypeName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.LNG_BUY_OR_SALE, purchaseIn.getType()));
        });

        // 导出 Excel
        ExcelUtils.write(response, "合同信息.xls", "数据", ContractInfoRespVO.class,
                rlist);
    }

}